"""
基础智能体类 - 所有专家智能体的基类
提供通用功能和标准接口
"""

import asyncio
from typing import List, Dict, Any, Optional
from datetime import datetime
from abc import ABC, abstractmethod

from ..core.interfaces import AgentInterface, ToolInterface, Task, TaskStatus
from ..core.events import EventEmitter
from ..core.container import container
from ..lightrag_engine.rag_controller import RAGController


class BaseAgent(AgentInterface, EventEmitter):
    """基础智能体类"""
    
    def __init__(self, name: str, capabilities: List[str]):
        super().__init__()
        self._name = name
        self._capabilities = capabilities
        self.available_tools: Dict[str, ToolInterface] = {}
        self.rag_controller: Optional[RAGController] = None
        self._initialized = False
    
    @property
    def name(self) -> str:
        return self._name
    
    @property
    def capabilities(self) -> List[str]:
        return self._capabilities.copy()
    
    async def initialize(self):
        """初始化智能体"""
        if self._initialized:
            return
        
        try:
            # 获取RAG控制器
            self.rag_controller = container.rag_controller()
            # Mock RAG控制器不需要初始化
            if hasattr(self.rag_controller, 'initialize'):
                await self.rag_controller.initialize()
            
            # 初始化智能体特定的组件
            await self._initialize_agent_specific()
            
            self._initialized = True
            
            await self.emit("agent_initialized", {
                "agent_name": self.name,
                "capabilities": self.capabilities,
                "available_tools": list(self.available_tools.keys())
            })
            
        except Exception as e:
            await self.emit_error("agent_initialization", e)
            raise
    
    @abstractmethod
    async def _initialize_agent_specific(self):
        """智能体特定的初始化逻辑"""
        pass
    
    async def process_task(self, task: Task) -> Task:
        """处理任务 - 模板方法"""
        if not self._initialized:
            await self.initialize()
        
        try:
            # 检查是否能处理任务
            if not await self.can_handle_task(task):
                task.status = TaskStatus.FAILED
                task.result = {"error": f"Agent {self.name} cannot handle task type: {task.task_type}"}
                return task
            
            await self.emit("task_processing_started", {
                "agent_name": self.name,
                "task_id": task.id,
                "task_type": task.task_type
            })
            
            # 更新任务状态
            task.status = TaskStatus.IN_PROGRESS
            task.metadata = task.metadata or {}
            task.metadata[f"{self.name}_started_at"] = datetime.now().isoformat()
            
            # 执行具体的任务处理逻辑
            result = await self._process_task_internal(task)
            
            # 更新任务结果
            task.result = result
            task.status = TaskStatus.COMPLETED
            task.metadata[f"{self.name}_completed_at"] = datetime.now().isoformat()
            
            await self.emit("task_processing_completed", {
                "agent_name": self.name,
                "task_id": task.id,
                "task_type": task.task_type
            })
            
            return task
            
        except Exception as e:
            task.status = TaskStatus.FAILED
            task.result = {"error": str(e), "agent": self.name}
            task.metadata[f"{self.name}_failed_at"] = datetime.now().isoformat()
            
            await self.emit_error("task_processing", e)
            return task
    
    @abstractmethod
    async def _process_task_internal(self, task: Task) -> Dict[str, Any]:
        """内部任务处理逻辑 - 子类实现"""
        pass
    
    async def can_handle_task(self, task: Task) -> bool:
        """检查是否能处理任务 - 默认实现"""
        # 基于任务类型和智能体能力判断
        task_keywords = task.task_type.lower().split('_')
        
        for capability in self.capabilities:
            capability_keywords = capability.lower().split('_')
            if any(keyword in task_keywords for keyword in capability_keywords):
                return True
        
        return False
    
    def register_tool(self, tool: ToolInterface):
        """注册工具"""
        self.available_tools[tool.name] = tool
    
    async def use_tool(self, tool_name: str, **kwargs) -> Any:
        """使用工具"""
        if tool_name not in self.available_tools:
            raise ValueError(f"Tool {tool_name} not available for agent {self.name}")
        
        tool = self.available_tools[tool_name]
        
        try:
            result = await tool.execute(**kwargs)
            
            await self.emit("tool_used", {
                "agent_name": self.name,
                "tool_name": tool_name,
                "success": True
            })
            
            return result
            
        except Exception as e:
            await self.emit("tool_usage_failed", {
                "agent_name": self.name,
                "tool_name": tool_name,
                "error": str(e)
            })
            raise
    
    async def query_rag(
        self,
        query: str,
        template_name: str = "general_qa",
        **kwargs
    ) -> Dict[str, Any]:
        """查询RAG系统"""
        if not self.rag_controller:
            raise RuntimeError("RAG controller not initialized")
        
        return await self.rag_controller.process_query(
            query=query,
            template_name=template_name,
            **kwargs
        )
    
    async def analyze_with_context(
        self,
        query: str,
        context_data: Dict[str, Any],
        analysis_type: str = "general"
    ) -> Dict[str, Any]:
        """基于上下文进行分析"""
        try:
            # 构建包含上下文的查询
            context_str = self._format_context_data(context_data)
            enhanced_query = f"""
            分析类型: {analysis_type}
            查询: {query}
            
            上下文信息:
            {context_str}
            
            请基于上下文信息进行详细分析。
            """
            
            result = await self.query_rag(enhanced_query)
            
            # 增强结果信息
            if isinstance(result, dict):
                result["agent"] = self.name
                result["analysis_type"] = analysis_type
                result["context_used"] = True
            
            return result
            
        except Exception as e:
            await self.emit_error("analyze_with_context", e)
            return {"error": str(e), "agent": self.name}
    
    def _format_context_data(self, context_data: Dict[str, Any]) -> str:
        """格式化上下文数据"""
        formatted_parts = []
        
        for key, value in context_data.items():
            if isinstance(value, (str, int, float)):
                formatted_parts.append(f"{key}: {value}")
            elif isinstance(value, list):
                if value and isinstance(value[0], dict):
                    # 处理字典列表
                    formatted_parts.append(f"{key}:")
                    for i, item in enumerate(value[:5]):  # 限制数量
                        formatted_parts.append(f"  {i+1}. {self._format_dict_item(item)}")
                else:
                    formatted_parts.append(f"{key}: {', '.join(map(str, value[:10]))}")
            elif isinstance(value, dict):
                formatted_parts.append(f"{key}: {self._format_dict_item(value)}")
        
        return "\n".join(formatted_parts)
    
    def _format_dict_item(self, item: Dict[str, Any]) -> str:
        """格式化字典项"""
        key_value_pairs = []
        for k, v in item.items():
            if isinstance(v, (str, int, float)):
                key_value_pairs.append(f"{k}={v}")
        return "{" + ", ".join(key_value_pairs[:5]) + "}"
    
    async def get_agent_metrics(self) -> Dict[str, Any]:
        """获取智能体性能指标"""
        return {
            "agent_name": self.name,
            "capabilities": self.capabilities,
            "available_tools": list(self.available_tools.keys()),
            "initialized": self._initialized,
            "status": "active" if self._initialized else "inactive"
        }


class BaseTool(ToolInterface, EventEmitter):
    """基础工具类"""
    
    def __init__(self, name: str, description: str = ""):
        super().__init__()
        self._name = name
        self.description = description
        self._initialized = False
    
    @property
    def name(self) -> str:
        return self._name
    
    async def initialize(self):
        """初始化工具"""
        if self._initialized:
            return
        
        try:
            await self._initialize_tool_specific()
            self._initialized = True
            
            await self.emit("tool_initialized", {
                "tool_name": self.name,
                "description": self.description
            })
            
        except Exception as e:
            await self.emit_error("tool_initialization", e)
            raise
    
    async def _initialize_tool_specific(self):
        """工具特定的初始化逻辑"""
        pass
    
    async def execute(self, **kwargs) -> Any:
        """执行工具 - 模板方法"""
        if not self._initialized:
            await self.initialize()
        
        try:
            await self.emit("tool_execution_started", {
                "tool_name": self.name,
                "parameters": list(kwargs.keys())
            })
            
            result = await self._execute_internal(**kwargs)
            
            await self.emit("tool_execution_completed", {
                "tool_name": self.name,
                "success": True
            })
            
            return result
            
        except Exception as e:
            await self.emit("tool_execution_failed", {
                "tool_name": self.name,
                "error": str(e)
            })
            raise
    
    @abstractmethod
    async def _execute_internal(self, **kwargs) -> Any:
        """内部执行逻辑 - 子类实现"""
        pass


class AgentRegistry:
    """智能体注册表"""
    
    def __init__(self):
        self.agents: Dict[str, AgentInterface] = {}
        self.tools: Dict[str, ToolInterface] = {}
    
    def register_agent(self, agent: AgentInterface):
        """注册智能体"""
        self.agents[agent.name] = agent
    
    def register_tool(self, tool: ToolInterface):
        """注册工具"""
        self.tools[tool.name] = tool
    
    def get_agent(self, name: str) -> Optional[AgentInterface]:
        """获取智能体"""
        return self.agents.get(name)
    
    def get_tool(self, name: str) -> Optional[ToolInterface]:
        """获取工具"""
        return self.tools.get(name)
    
    def list_agents(self) -> List[str]:
        """列出所有智能体"""
        return list(self.agents.keys())
    
    def list_tools(self) -> List[str]:
        """列出所有工具"""
        return list(self.tools.keys())
    
    def get_agents_by_capability(self, capability: str) -> List[AgentInterface]:
        """根据能力获取智能体"""
        matching_agents = []
        for agent in self.agents.values():
            if capability.lower() in [cap.lower() for cap in agent.capabilities]:
                matching_agents.append(agent)
        return matching_agents


# 全局智能体注册表
agent_registry = AgentRegistry()